module profiler_mongo_mod

  use iso_c_binding
  use mongof_common_mod
  use datetime
  use string
  use container
  use flogger
  use params_mod
  use data_translators_utils_mod
  use profiler_mod

  implicit none

  private

  public profiler_mongo_write

  interface
    integer function profiler_mongoc_insert_platform(cid, name, lon, lat, z) result(res) bind(c, name='profiler_mongoc_insert_platform')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_float), intent(in) :: lon
      real(c_float), intent(in) :: lat
      real(c_float), intent(in) :: z
    end function profiler_mongoc_insert_platform

    integer function profiler_mongoc_insert_record(cid, name, timestamp, nlev, h, ua, va) &
                                               result(res) bind(c, name='profiler_mongoc_insert_record')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_double), intent(in) :: timestamp
      integer(c_int), intent(in) :: nlev
      real(c_float), intent(in), dimension(:) :: h
      real(c_float), intent(in), dimension(:) :: ua
      real(c_float), intent(in), dimension(:) :: va
    end function profiler_mongoc_insert_record
  end interface

contains

  subroutine profiler_mongo_write(mongo_uri, mongo_db, mongo_col, stations, records)

    character(*), intent(in) :: mongo_uri
    character(*), intent(in) :: mongo_db
    character(*), intent(in) :: mongo_col
    type(hash_table_type), intent(in) :: stations
    type(linked_list_type), intent(in) :: records

    integer(c_int) cid_station, cid_record
    character(10) sid
    type(linked_list_iterator_type) it

    call mongoc_init()

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri), trim(mongo_db), &
      trim(mongo_col) // '_stations' // char(0), cid_station), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri), trim(mongo_db), &
      trim(mongo_col) // '_records' // char(0), cid_record), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_create_platform_index(cid_station), __FILE__, __LINE__)
    call handle_mongo_error(mongoc_create_record_index(cid_record), __FILE__, __LINE__)

    it = linked_list_iterator(records)
    do while (.not. it%ended())
      select type (record => it%value)
      type is (profiler_record_type)
        sid = trim(record%station%name) // char(0)
        call handle_mongo_error(profiler_mongoc_insert_platform(cid_station, sid, &
          record%station%lon, record%station%lat, record%station%z), __FILE__, __LINE__)
        call handle_mongo_error(profiler_mongoc_insert_record(cid_record, sid, record%time%timestamp(), &
          record%pro%num_level, record%pro%h, record%pro%ua, record%pro%va), __FILE__, __LINE__)
      end select
      call it%next()
    end do

    call mongoc_final()

  end subroutine profiler_mongo_write

end module profiler_mongo_mod
